TypeScript is an easy to learn extension of JavaScript. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust TypeScript code.
In this article, we’ll look at the best practices to following when writing code with TypeScript, including stopping the use of triple-slash directives.
Also, we should merge function overloads that can be merged.
We look at why unbound methods should be called within their scope.
And we look at spacing and adding type annotations everywhere.
Stop Using Triple Slash Directives in Favor of ES6 Modules
Now that JavaScript has modules as a standard feature, we don’t have to use triple-slash directives to access TypeScript namespaces and modules anymore.
For instance, instead of writing:
/// <reference path="foo" />
We should write:
import foo from './foo';
or:
import { bar } from './foo';
Require Consistent Spacing Around Type Annotations
We should have consistent spacing around data type annotations for improved readability.
For instance, we can write:
let foo: string = "bar";
The code above is readable.
Require Type Annotations to Exist
We should add data type annotations wherever we can.
This way, we get type checks and autocomplete everywhere in our project.
For instance, we should write:
class ContainsText {
text: string;
bar: string = 'text';
}
We have data type annotations to label the types of variables and have them in variables that have a value assigned to them for consistency.
Enforce Unbound Methods are Called within their Expected Scope
We should make sure that a method isn’t used outside of their expected scope.
For instance, if we have:
class Foo {
public log(): void {
console.log(this);
}
}
Then we shouldn’t call log
as follows:
const foo = new Foo();
const log = instance.log;
log();
Since log
is now at the top level, this
would be the global object, which is window
in the browser and global
in Node.
Instead, we should call it by writing:
const foo = new Foo();
foo.log();
If Overloads can be Unified into One by a Union or Optional Parameter, then we should Merge them Together
If our functions have overloads that can be merged together, then we should do so.
For instance, instead of writing:
function f(x: number): void;
function f(x: string): void;
We should write:
function f(x: number|string): void;
And if we have:
f(): void;
f(...arr: number[]): void;
Then we should write:
function f(arr?: ...number[]): void;
This way, we reduce the number of declarations that are needed.
Conclusion
We should reduce the number of functions declarations that are needed by merging overloads that can be merged together.
Also, we should make sure that anything that references this
are called within their expected scope.
If we’re still using triple-slash directives, then we should turn them to module imports wherever we can.